#ifndef TMUTEX_H
#define TMUTEX_H

//#define RELEASE

//#ifdef RELEASE
//    #define SDL_THREADING
//#endif

#if defined SDL_THREADING
    #include "SDL/SDL_mutex.h"
    #define MUTEX_H "sdl_mutex.h"
    #define MUTEXTYPE SDL_ThreadingPolicy
#else
    #define MUTEXTYPE Single_ThreadingPolicy
#endif


namespace Den
{
        struct Mutex
        {
                virtual ~Mutex(){}
                virtual void Acquire(void) const = 0;
                virtual void Release(void) const = 0;
        };
        //---------------------------------------------------------------------
        struct Single_ThreadingPolicy
        {
                ~Single_ThreadingPolicy(){}
                 void Acquire(void) const{}
                 void Release(void) const{}
        };
        //---------------------------------------------------------------------
#if defined SDL_THREADING
        struct SDL_ThreadingPolicy : public Mutex
        {
                SDL_ThreadingPolicy(): mutex(SDL_CreateMutex()){}
                virtual ~SDL_ThreadingPolicy()   {SDL_DestroyMutex(mutex);}
                virtual void Release(void) const {SDL_UnlockMutex(mutex); }
                virtual void Acquire(void) const {SDL_LockMutex(mutex);   }

            private:
                SDL_mutex* mutex;
        };
#endif
        //---------------------------------------------------------------------
        template < class MUTEX = MUTEXTYPE >
        struct Lockable
        {
            struct Lock
            {
                    Lock(const Mutex& mutex): mutex(mutex){ mutex.Acquire(); }
                   ~Lock(){ mutex.Release(); }
                private:
                    const Mutex& mutex;
            };
            Lockable(): mutex(){}
        protected:
            const MUTEX mutex;
        private:
            Lockable(const Lockable&);
            Lockable& operator=(const Lockable&);
        };
        //---------------------------------------------------------------------


}//Den


#endif // TMUTEX_H
